package com.ruoyi.exportCustomer.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.helper.LoginHelper;
import com.ruoyi.common.utils.BeanCopyUtils;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.JsonUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.customer.common.DisCustomerBo;
import com.ruoyi.customer.common.DisCustomerRequestBo;
import com.ruoyi.customer.domain.*;
import com.ruoyi.customer.domain.bo.ExportInfoBo;
import com.ruoyi.customer.domain.vo.CustomerImportVo;
import com.ruoyi.customer.mapper.CustomerMapper;
import com.ruoyi.customer.mapper.RemarkMapper;
import com.ruoyi.customer.mapper.TmpCustomerMapper;
import com.ruoyi.customer.mapper.TotalComsterMapper;
import com.ruoyi.customer.service.CommonService;
import com.ruoyi.customer.service.ITotalComsterService;
import com.ruoyi.customerPool.service.ICustomerPoolService;
import com.ruoyi.enums.BusTypeEnum;
import com.ruoyi.exportCustomer.domain.ExportLog;
import com.ruoyi.exportCustomer.domain.LogsInfo;
import com.ruoyi.exportCustomer.domain.bo.ExportLogBo;
import com.ruoyi.exportCustomer.domain.vo.ExportLogVo;
import com.ruoyi.exportCustomer.mapper.ExportLogMapper;
import com.ruoyi.exportCustomer.service.IExportLogService;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;

/**
 * 导入记录Service业务层处理
 *
 * @author ruoyi
 * @date 2023-08-23
 */
@RequiredArgsConstructor
@Service
public class ExportLogServiceImpl implements IExportLogService {

    private final ExportLogMapper baseMapper;

    private final ICustomerPoolService iCustomerPoolService;

    private final ITotalComsterService totalComsterService;

    private final TotalComsterMapper totalComsterMapper;

    private final TmpCustomerMapper tmpCustomerMapper;

    private final CustomerMapper customerMapper;

    private final RemarkMapper remarkMapper;

    private final CommonService commonService;


    /**
     * 查询导入记录列表
     */
    @Override
    public TableDataInfo<ExportLogVo> queryPageList(ExportLogBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<ExportLog> lqw = buildQueryWrapper(bo);
        Page<ExportLogVo> result = baseMapper.selectVoPage(pageQuery.build(),
                lqw.orderByDesc(ExportLog::getCreateTime));
        return TableDataInfo.build(result);
    }

    /**
     * 查询导入记录列表
     */
    @Override
    public TableDataInfo<LogsInfo> queryPageList(LogsInfo bo, PageQuery pageQuery) {
        Page<LogsInfo> page = new Page<>();
        page.setSize(pageQuery.getPageSize());
        page.setCurrent(pageQuery.getPageNum());
        Page<LogsInfo> result = baseMapper.selectListByPage(page, Constants.TMPTABLENAME + bo.getPc(), bo.getName(),
                bo.getTel(), bo.getFlag(), bo.getType(), bo.getLevel(), bo.getSource());
        return TableDataInfo.build(result);
    }

    /**
     * 查询导入记录列表
     */
    @Override
    public List<ExportLogVo> queryList(ExportLogBo bo) {
        LambdaQueryWrapper<ExportLog> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<ExportLog> buildQueryWrapper(ExportLogBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<ExportLog> lqw = Wrappers.lambdaQuery();
        lqw.like(StringUtils.isNotBlank(bo.getPc()), ExportLog::getPc, bo.getPc());
        lqw.eq(StringUtils.isNotBlank(bo.getSucessCnt()), ExportLog::getSucessCnt, bo.getSucessCnt());
        lqw.eq(StringUtils.isNotBlank(bo.getErrorCnt()), ExportLog::getErrorCnt, bo.getErrorCnt());
        lqw.like(StringUtils.isNotBlank(bo.getTabName()), ExportLog::getTabName, bo.getTabName());
        return lqw;
    }

    /**
     * 新增导入记录
     */
    @SneakyThrows
    @Override
    @Transactional(rollbackFor = Exception.class)
    public R importData(MultipartFile file, String batchLogo) {
        if (file == null) {
            return R.fail("未发现文件！");
        }
        // 批次调整
        String dateToStr = "";
        if (!StringUtils.isNotBlank(batchLogo)) {
            Long userId = LoginHelper.getUserId();
            dateToStr = DateUtils.parseDateToStr(DateUtils.YYYYMMDDHHMMSS, DateUtils.getNowDate()) + userId;
        } else {
            // 防止输入重复
            Long l = baseMapper.selectCount(new LambdaQueryWrapper<ExportLog>().eq(ExportLog::getPc, batchLogo));
            // 批次号已经存在
            if (l > 0) {
                dateToStr = batchLogo + "_" + DateUtils.parseDateToStr(DateUtils.YYYYMMDDHHMMSS, DateUtils.getNowDate());
            } else {
                dateToStr = batchLogo;
            }
        }
        // 批次号
        System.out.println("批次号：" + dateToStr);
        String tableName = Constants.TMPTABLENAME + dateToStr;
        List<CustomerImportVo> customerImportVos = ExcelUtil.importExcel(file.getInputStream(), CustomerImportVo.class);
        if (!CollectionUtils.isEmpty(customerImportVos)) {
            // 导入和自身去重
            iCustomerPoolService.exportTotalCustom(customerImportVos, tableName, dateToStr);
            // 记录成功数据、失败数据
            baseMapper.importTotalCustomer(tableName, dateToStr, LoginHelper.getLoginUser().getNickName());
            // 手机号码如果已经存在，需要查看目前状态 是未分配，还是那个部门或个人中

            // 查询当中失败的信息 保存备注、姓名
            List<CustomerImportVo> errMsg = tmpCustomerMapper.importDataErrMsg(tableName);
            if (!CollectionUtils.isEmpty(errMsg)) {
                for (CustomerImportVo customerImportVo : errMsg) {
                    String tel = customerImportVo.getTel();
                    // 备注信息
                    String bz = customerImportVo.getBz();
                    String newName = customerImportVo.getName();
                    // 更新总库表信息
                    totalComsterMapper.updateTotalRemarkName(tel, bz, newName);

                    QueryWrapper<Customer> query = Wrappers.query();
                    query.eq("deleted", "0");
                    query.eq("tel", tel);
                    List<Customer> customers = customerMapper.selectList(query);
                    // 是否存在客户表
                    if (!CollectionUtils.isEmpty(customers)) {
                        if (!StringUtils.isNotBlank(bz)) {
                            continue;
                        }
                        StringBuilder stringBuilder = new StringBuilder();
                        String remarkInfo =
                                bz + "--" + LoginHelper.getLoginUser().getNickName() + "[" + DateUtils.parseDateToStr(
                                        DateUtils.YYYY_MM_DD_HH_MM_SS, DateUtils.getNowDate()) + "]";
                        stringBuilder.append(remarkInfo);
                        stringBuilder.append("<br/>");
                        // 更新备注信息到
                        for (Customer customer : customers) {
                            String before = customer.getBz();
                            String name = customer.getName();
                            stringBuilder.append(before);
                            Customer customerInfo = new Customer();
                            customerInfo.setName(newName + "-" + name);
                            customerInfo.setId(customer.getId());
                            customerInfo.setBz(stringBuilder.toString());
                            customerMapper.updateById(customerInfo);

                            String newOldJson = JsonUtils.toJsonString(customerInfo);
                            String oldOldJson = JsonUtils.toJsonString(customer);
                            CustomerChange newCustomerChange = BeanUtil.toBean(customerInfo, CustomerChange.class);
                            CustomerChange oldCustomerChange = BeanUtil.toBean(customer, CustomerChange.class);
                            Map<String, Object> mapChangeInfo = new HashMap<>();
                            mapChangeInfo.put("customerId", customer.getId());
                            mapChangeInfo.put("tel", customer.getTel());
                            mapChangeInfo.put("createId", 14L);
                            mapChangeInfo.put("createBy", "管理员");
                            mapChangeInfo.put("type", "customerInfoChange");
                            commonService.customerChangeRecord(oldCustomerChange, oldOldJson, newCustomerChange, newOldJson, mapChangeInfo, "1");


                            // 新增一条备注记录信息
                            Remark remark = new Remark();
                            remark.setContent(bz);
                            remark.setCustomerId(customer.getId());
                            remark.setCreateBy(LoginHelper.getLoginUser().getNickName());
                            remark.setUserId(LoginHelper.getUserId());
                            remarkMapper.insert(remark);
                        }
                    }
                }
            }
            inertBathTelRecord(tableName, batchLogo);
            return R.ok("操作成功!");
        } else {
            return R.fail("未查询到数据");
        }
    }

    /**
     * 更新总库、客户表
     */
    private void inertBathTelRecord(String tableName, String bathLog) {
        TelBathRecord telBathRecord = new TelBathRecord();
        telBathRecord.setTableName(tableName);
        telBathRecord.setBathLog(bathLog);
        SpringUtils.context().publishEvent(telBathRecord);
    }

    @Override
    @Transactional
    public R oneKeyIssueToDept(ExportInfoBo infoBo) {
        List<LogsInfo> logsInfos = infoBo.getLogsInfos();

        if (CollectionUtils.isEmpty(logsInfos)) {
            throw new ServiceException("数据信息不存在");
        }

        List<String> telList = logsInfos.stream().map(LogsInfo::getTel).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(telList)) {
            throw new ServiceException("数据信息不存在");
        }

        if (CollectionUtils.isEmpty(infoBo.getDeptBos())) {
            throw new ServiceException("部门信息参数缺失");
        }

        // 根据批次号查找对应的数据
        QueryWrapper<TotalComster> query = Wrappers.query();
        query.in("mobile", telList);
        List<TotalComster> totalComsters = totalComsterMapper.selectList(query);
        if (CollectionUtils.isEmpty(totalComsters)) {
            throw new ServiceException("客户信息未找到");
        }

        List<DisCustomerBo> customerBos = totalComsters.stream().map(it -> {
            DisCustomerBo disCustomerBo = new DisCustomerBo();
            disCustomerBo.setId(it.getId());
            disCustomerBo.setTel(it.getMobile());
            disCustomerBo.setName(it.getName());
            return disCustomerBo;
        }).collect(Collectors.toList());

        // 失败数据下发 （3、手机号码有效存在 (在总库当中已经存在) 4、手机号无效存在(在总库中存在手机号码但是已经删除) ）
        DisCustomerRequestBo oneKeyIssueBo = new DisCustomerRequestBo();
        BeanCopyUtils.copy(infoBo, oneKeyIssueBo);
        oneKeyIssueBo.setDisCustomerBos(customerBos);
        totalComsterService.oneKeyIssueToDept(oneKeyIssueBo, BusTypeEnum.EXPORT_CUSTOMER.getCode());
        return R.ok();
    }


    @Override
    @Transactional
    public R oneKeyIssueToUser(ExportInfoBo infoBo) {
        List<LogsInfo> logsInfos = infoBo.getLogsInfos();

        List<String> telList = logsInfos.stream().map(LogsInfo::getTel).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(telList)) {
            throw new ServiceException("数据信息不存在");
        }

        if (CollectionUtils.isEmpty(infoBo.getUserBos())) {
            throw new ServiceException("用户参数缺失");
        }

        // 根据批次号查找对应的数据
        QueryWrapper<TotalComster> query = Wrappers.query();
        query.eq("del_flag", 0);
        query.in("mobile", telList);
        List<TotalComster> totalComsters = totalComsterMapper.selectList(query);
        if (CollectionUtils.isEmpty(totalComsters)) {
            throw new ServiceException("客户信息未找到");
        }

        List<DisCustomerBo> customerBos = totalComsters.stream().map(it -> {
            DisCustomerBo disCustomerBo = new DisCustomerBo();
            disCustomerBo.setId(it.getId());
            disCustomerBo.setTel(it.getMobile());
            disCustomerBo.setName(it.getName());
            return disCustomerBo;
        }).collect(Collectors.toList());

        DisCustomerRequestBo oneKeyIssueBo = new DisCustomerRequestBo();
        BeanCopyUtils.copy(infoBo, oneKeyIssueBo);
        oneKeyIssueBo.setDisCustomerBos(customerBos);
        totalComsterService.oneKeyIssueToUser(oneKeyIssueBo, BusTypeEnum.EXPORT_CUSTOMER.getCode());
        return R.ok();
    }

}
